<template>
  <div class="app-container">
    <el-container>
      <!-- 左侧树 -->
      <el-aside width="580px">
        <div class="filter-container">
          <el-input v-model="filterText" placeholder="输入关键字进行过滤" style="width:200px; padding-right:10px;" />
          <el-button class="filter-item" style="margin-bottom: 1px !important;" type="primary" size="mini" icon="el-icon-search" @click="refreshTree">
            刷新
          </el-button>
          <el-button :loading="dataLoading" class="filter-item" style="margin-bottom: 1px !important;" type="warning" size="mini" icon="el-icon-refresh" @click="resetOrgIndex">
            重建索引
          </el-button>
          <el-button class="filter-item" style="margin-bottom: 1px !important;" type="danger" size="small" icon="el-icon-upload" @click="handleUpload">
            导入
          </el-button>
        </div>
        <el-tree
          ref="tree"
          :props="treeProps"
          :indent="16"
          node-key="orgCode"
          :render-after-expand="true"
          :highlight-current="true"
          :check-on-click-node="true"
          :expand-on-click-node="false"
          :filter-node-method="filterNode"
          :lazy="true"
          :load="loadSubData"
          @node-click="handleNodeClick"
        />
      </el-aside>
      <el-main style="padding-top: 10px;">
        <div class="filter-container">
          <el-button v-if="viewTemp.orgCode !== null" type="success" size="mini" @click="handleCreate(viewTemp.orgCode, true)">
            新增下级
          </el-button>
          <el-button v-if="viewTemp.pOrgCode !== null && viewTemp.orgCode !== ''" type="success" size="mini" @click="handleCreate(viewTemp.pOrgCode, true)">
            新增同级
          </el-button>
          <el-button v-if="viewTemp.pOrgCode !== null && viewTemp.orgCode !== ''" type="primary" size="mini" @click="handleUpdate(viewTemp)">
            编辑
          </el-button>
          <el-button v-if="viewTemp.pOrgCode !== null && viewTemp.orgCode !== '' && viewTemp.isLeaf" size="mini" type="danger" @click="handleDelete(viewTemp)">
            删除
          </el-button>
        </div>
        <el-form :model="viewTemp" :disabled="true" label-position="right" label-width="150px" style="width: 500px; margin-left:50px;">
          <el-form-item label="机构编号" prop="orgCode">
            <el-input v-model="viewTemp.orgCode" />
          </el-form-item>
          <el-form-item label="机构名称" prop="orgName">
            <el-input v-model="viewTemp.orgName" />
          </el-form-item>
          <el-form-item label="上级机构编号" prop="pOrgCode">
            <el-input v-model="viewTemp.pOrgCode" />
          </el-form-item>
          <el-form-item label="机构类型" prop="orgType">
            <el-select v-model="viewTemp.orgType">
              <el-option v-for="item in orgTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="机构展示顺序" prop="orgSeq">
            <el-input-number v-model="viewTemp.orgSeq" :min="0" :max="99999999" :precision="0" :controls="false" />
          </el-form-item>
          <el-form-item label="机构联系电话" prop="orgTel">
            <el-input v-model="viewTemp.orgTel" />
          </el-form-item>
          <el-form-item label="地区代号" prop="areaCode">
            <AreaCascader v-if="reloaded" ref="AreaCascader" v-model="viewTemp.areaCode" :clearable="true" :show-all-levels="true" />
          </el-form-item>
          <el-form-item label="机构地址" prop="orgAddress">
            <el-input v-model="viewTemp.orgAddress" autosize type="textarea" :rows="3" />
          </el-form-item>
          <el-form-item label="营业时间" prop="bizTime">
            <el-input v-model="viewTemp.bizTime" />
          </el-form-item>
          <el-form-item label="联系人" prop="linkMan">
            <el-input v-model="viewTemp.linkMan" />
          </el-form-item>
          <el-form-item label="联系方式" prop="linkPhone">
            <el-input v-model="viewTemp.linkPhone" />
          </el-form-item>
          <el-form-item label="物理机构号" prop="phyCode">
            <el-input v-model="viewTemp.phyCode" />
          </el-form-item>
          <el-form-item label="物理机构名称" prop="phyName">
            <el-input v-model="viewTemp.phyName" />
          </el-form-item>
          <el-form-item label="所属机构编号(沙盘)" prop="ssjgbh">
            <el-input v-model="viewTemp.ssjgbh" />
          </el-form-item>
          <el-form-item label="启用标记" prop="enableFlag">
            <el-select v-model="viewTemp.enableFlag" class="filter-item">
              <el-option v-for="item in enableFlagOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-form>
      </el-main>
    </el-container>

    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" top="3vh" width="800px" :close-on-click-modal="false" :close-on-press-escape="false" center>
      <el-form ref="dataForm" :rules="rules" :model="temp" label-position="right" label-width="120px" class="form-center">
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="机构编号" prop="orgCode">
              <el-input v-model="temp.orgCode" maxlength="64" :disabled="dialogStatus==='update'" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="机构名称" prop="orgName">
              <el-input v-model="temp.orgName" maxlength="128" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="上级机构编号" prop="pOrgCode">
              <el-input v-model="temp.pOrgCode" :disabled="true" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="机构类型" prop="orgType">
              <el-select v-model="temp.orgType" clearable class="filter-item">
                <el-option v-for="item in orgTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="机构展示顺序" prop="orgSeq">
              <el-input-number v-model="temp.orgSeq" :min="0" :max="99999999" :precision="0" :controls="false" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="机构联系电话" prop="orgTel">
              <el-input v-model="temp.orgTel" maxlength="32" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="地区代号" prop="areaCode">
              <AreaCascader ref="AreaCascader2" v-model="temp.areaCode" :clearable="true" :show-all-levels="true" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="机构地址" prop="orgAddress">
              <el-input v-model="temp.orgAddress" autosize type="textarea" :rows="3" maxlength="128" show-word-limit />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="营业时间" prop="bizTime">
              <el-input v-model="temp.bizTime" maxlength="64" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="联系人" prop="linkMan">
              <el-input v-model="temp.linkMan" maxlength="64" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="联系方式" prop="linkPhone">
              <el-input v-model="temp.linkPhone" maxlength="64" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="物理机构号" prop="phyCode">
              <el-input v-model="temp.phyCode" maxlength="8" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="物理机构名称" prop="phyName">
              <el-input v-model="temp.phyName" maxlength="64" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="所属机构编号(沙盘)" prop="ssjgbh">
              <el-input v-model="temp.ssjgbh" maxlength="8" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="启用标记" prop="enableFlag">
              <el-select v-model="temp.enableFlag" clearable class="filter-item">
                <el-option v-for="item in enableFlagOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button :loading="ajaxSubmiting" type="primary" @click="dialogStatus==='create'?createData(false):updateData()">
          保存
        </el-button>
      </div>
    </el-dialog>

    <el-dialog title="Excel导入机构信息" :visible.sync="uploadExcelDialogVisible" center>
      <div class="app-container">
        <el-upload
          ref="upload"
          action="customized"
          :limit="1"
          accept=".xls,.xlsx"
          :http-request="handleExcelUpload"
          :auto-upload="false"
        >
          <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
          <el-button :loading="fileUploading" style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
          <el-button style="margin-left: 10px;" size="small" type="info" @click="handleDownloadTemplate">下载模板</el-button>
          <div slot="tip" class="el-upload__tip">只能上传xls/xlsx文件</div>
        </el-upload>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { getSubOrgList, createOrgInfo, updateOrgInfo, deleteOrgInfo, updateOrgIndex, exportOrgInfoTemplate, importOrgInfo } from '@/api/base/auth/orgInfo'
import { setOptionData } from '@/utils/dict'
import { saveRespExcel } from '@/utils'
import AreaCascader from '@/components/Area/cascader'

export default {
  name: 'OrgInfo',
  components: { AreaCascader },
  data() {
    return {
      treeProps: {
        label: 'orgName',
        isLeaf: 'leaf'
      },
      isSaveAndContinue: false,
      orgTypeOptions: [],
      enableFlagOptions: [],
      dataLoading: false,
      viewTemp: {
        id: null,
        orgCode: null,
        orgName: null,
        pOrgCode: null,
        orgType: null,
        orgSeq: null,
        orgTel: null,
        areaCode: null,
        orgAddress: null,
        linkMan: null,
        linkPhone: null,
        enableFlag: null,
        phyCode: null,
        phyName: null,
        ssjgbh: null
      },
      reloaded: true,
      temp: {
        orgCode: '',
        orgName: '',
        pOrgCode: '',
        orgType: '',
        orgSeq: null,
        orgTel: '',
        areaCode: '',
        orgAddress: '',
        linkMan: '',
        enableFlag: 'Y',
        phyCode: null,
        phyName: null,
        ssjgbh: null
      },
      filterText: '',
      dialogFormVisible: false,
      uploadExcelDialogVisible: false,
      fileUploading: false,
      dialogStatus: '',
      textMap: {
        update: '更新机构信息',
        create: '新增机构信息'
      },
      rules: {
        orgCode: [{ required: true, message: '机构编号不能为空', trigger: 'change' }],
        orgName: [{ required: true, message: '机构名称不能为空', trigger: 'change' }],
        pOrgCode: [{ max: 64, message: '上级机构编号不能大于64个字符', trigger: 'change' }],
        orgType: [{ required: true, message: '机构类型不能为空', trigger: 'change' }],
        orgSeq: [{ required: true, message: '机构展示顺序不能为空', trigger: 'change' }],
        enableFlag: [{ required: true, message: '启用标记不能为空', trigger: 'change' }]
      },
      ajaxSubmiting: false
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  created() {
    // 初始化数据字典
    // 加载下拉数据
    const optionsMap = new Map()
    optionsMap.set('BASE_ORG_TYPE', this.orgTypeOptions)
    optionsMap.set('ENABLE_FLAG', this.enableFlagOptions)
    setOptionData(optionsMap)
  },
  methods: {
    resetOrgIndex() {
      this.$msgbox({
        type: 'warning',
        title: '确认',
        message: '即将对全部机构进行索引重建处理,确认需要重建索引?',
        showCancelButton: true,
        showClose: false,
        closeOnPressEscape: false,
        closeOnClickModal: false,
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            this.dataLoading = true
            updateOrgIndex().then((response) => {
              this.$message({
                message: '全部机构索引重建处理成功!',
                type: 'success'
              })
              done()
              instance.confirmButtonLoading = false
              this.dataLoading = false
            }, (response) => {
              done()
              instance.confirmButtonLoading = false
              this.dataLoading = false
            })
          } else {
            done()
          }
        }
      }).catch(() => {})
    },
    loadSubData(node, resolve) {
      if (node.level === 0) {
        return resolve([{
          orgCode: '',
          orgName: '机构信息',
          pOrgCode: '',
          orgType: '',
          orgSeq: null,
          orgTel: '',
          areaCode: '',
          orgAddress: '',
          linkMan: '',
          linkPhone: '',
          enableFlag: '',
          leaf: false,
          children: []
        }])
      } else {
        getSubOrgList(node.data.orgCode).then(response => {
          resolve(response.data)
        })
      }
    },
    handleNodeClick(data, node, other) {
      this.reloaded = false
      this.viewTemp = Object.assign({}, data)
      this.viewTemp.isLeaf = node.isLeaf
      this.$nextTick(() => {
        this.reloaded = true
      })
    },
    filterNode(value, data, node) {
      if (!value) {
        return true
      }
      return (data.orgName.indexOf(value) !== -1 || data.orgCode.indexOf(value) !== -1)
    },
    refreshTree() {
      // 本处使用了el-tree内部方法，存在升级危险
      const pNode = this.$refs.tree.getNode('')
      var theChildren = pNode.childNodes
      theChildren.splice(0, theChildren.length)
      pNode.loaded = false
      pNode.expanded = false
    },
    resetTree() {
      this.filterText = ''
      this.refreshTree()
    },
    resetTemp() {
      this.temp = {
        orgCode: '',
        orgName: '',
        pOrgCode: '',
        orgType: '',
        orgSeq: null,
        orgTel: '',
        areaCode: '',
        orgAddress: '',
        linkMan: '',
        linkPhone: '',
        enableFlag: 'Y'
      }
    },
    handleCreate(pOrgCode, isResetTemp) {
      if (isResetTemp) {
        this.resetTemp()
      }
      this.temp.pOrgCode = pOrgCode
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    createData(isSaveAndContinue) {
      this.isSaveAndContinue = isSaveAndContinue
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          this.ajaxSubmiting = true
          createOrgInfo(this.temp).then((response) => {
            response.data.leaf = true
            const data = response.data
            const pNode = this.$refs.tree.getNode(this.temp.pOrgCode)
            if (pNode) {
              this.insertNodeByOrgSeq(data, pNode)
              pNode.isLeaf = false
            }
            this.$message({
              message: '机构信息保存成功!',
              type: 'success'
            })
            this.ajaxSubmiting = false
            if (this.isSaveAndContinue) {
              this.handleCreate(this.temp.pOrgCode, false)
            } else {
              this.dialogFormVisible = false
            }
          }, () => {
            this.ajaxSubmiting = false
          })
        }
      })
    },
    insertNodeByOrgSeq(data, pNode) {
      // 遍历childNodes，确定新创建的子节点要插入哪个位置
      var childNodes = pNode.childNodes
      var hadCreateNode = false
      for (var i = 0; i < childNodes.length; i++) {
        var childNode = childNodes[i]
        if (childNode.data.orgSeq === data.orgSeq) {
          if (childNode.data.orgCode <= data.orgCode) {
            this.$refs.tree.insertAfter(data, childNode)
            hadCreateNode = true
            break
          } else {
            this.$refs.tree.insertBefore(data, childNode)
            hadCreateNode = true
            break
          }
        } else if (childNode.data.orgSeq > data.orgSeq) {
          this.$refs.tree.insertBefore(data, childNode)
          hadCreateNode = true
          break
        }
      }
      if (!hadCreateNode) { // 如果该parentNode无子节点，或者orgSeq比children的都要大
        this.$refs.tree.append(data, pNode)
      }
    },
    handleUpdate(row) {
      this.temp = Object.assign({}, row) // copy obj
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    updateData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          this.ajaxSubmiting = true
          updateOrgInfo(this.temp).then((response) => {
            const node = this.$refs.tree.getNode(this.temp.orgCode)
            if (node) {
              if (node.data.orgSeq === this.temp.orgSeq) { // 节点orgSeq无变化
                node.data = Object.assign(node.data, this.temp)
              } else {
                // 如果orgSeq有修改。先remove再重新insert，实现排序插入
                const pNode = this.$refs.tree.getNode(this.temp.pOrgCode)
                this.$refs.tree.remove(node)
                this.insertNodeByOrgSeq(this.temp, pNode)
              }
            }
            if (this.viewTemp.orgCode === this.temp.orgCode) {
              this.viewTemp = Object.assign({}, this.temp)
            }
            this.dialogFormVisible = false
            this.ajaxSubmiting = false

            this.$message({
              message: '机构数据更新成功!',
              type: 'success'
            })
          }, () => {
            this.ajaxSubmiting = false
          })
        }
      })
    },
    submitUpload() {
      this.$refs.upload.submit()
    },
    handleUpload() {
      this.uploadExcelDialogVisible = true
    },
    handleExcelUpload(file) {
      if (!file || !file.file) {
        return function() {
          Promise.resolve(file)
        }
      }
      this.fileUploading = true
      importOrgInfo(file).then(response => {
        this.resetTree()
        this.$message({
          message: '批量导入机构信息成功!',
          type: 'success'
        })
        this.uploadExcelDialogVisible = false
        this.fileUploading = false
      }, response => {
        this.fileUploading = false
      })
    },
    handleDownloadTemplate() {
      this.downloadLoading = true
      exportOrgInfoTemplate().then(response => {
        saveRespExcel(response)
        this.downloadLoading = false
      }, response => {
        this.downloadLoading = false
      })
    },
    handleDelete(row) {
      this.$msgbox({
        type: 'warning',
        title: '确认',
        message: '即将删除机构' + row.orgCode + ',确认删除数据?',
        showCancelButton: true,
        showClose: false,
        closeOnPressEscape: false,
        closeOnClickModal: false,
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            deleteOrgInfo(row.orgCode).then((response) => {
              const node = this.$refs.tree.getNode(row.orgCode)
              if (node) {
                this.$refs.tree.remove(node)
              }
              this.$message({
                message: '机构' + row.orgCode + '删除成功!',
                type: 'success'
              })
              done()
              instance.confirmButtonLoading = false
            }, (response) => {
              done()
              instance.confirmButtonLoading = false
            })
          } else {
            done()
          }
        }
      }).catch(() => {})
    }
  }
}
</script>
